from django import forms
from web import models
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
import random
from sass import settings
from utils.tencent.sms import send_sms_single
from django_redis import get_redis_connection
from utils import encrypt
from web.form.bootstrap import BootstrapForm


class RegisterModelForm(BootstrapForm, forms.ModelForm):
    phone = forms.CharField(label='手机号', validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机格式错误'), ])
    password = forms.CharField(
        min_length=1,
        max_length=64,
        error_messages={
            'min_length': "密码长度不能小于8位",
            'max_length': "密码长度不能大于64位",
        },
        widget=forms.PasswordInput(), label='密码')
    confirm_password = forms.CharField(
        min_length=1,
        max_length=64,
        error_messages={
            'min_length': "密码长度不能小于8位",
            'max_length': "密码长度不能大于64位",
        },
        widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': '请输入'}),
        label='重复密码')
    code = forms.CharField(label="验证码")

    class Meta:
        model = models.User
        fields = ['username', 'email', 'phone', 'password', 'confirm_password', 'code']  # 这个验证的时候是有优先级顺序的

    # 验证
    def clean_username(self):
        username = self.cleaned_data['username']
        return username

    def clean_email(self):
        email = self.cleaned_data['email']
        exists = models.User.objects.filter(email=email).exists()
        if exists:
            raise ValidationError('邮箱已经存在')
        return email

    def clean_phone(self):
        phone = self.cleaned_data['phone']
        exists = models.User.objects.filter(phone=phone).exists()
        if exists:
            raise ValidationError('手机号已经注册')
        return phone

    def clean_password(self):
        password = self.cleaned_data['password']
        # 加密，并进行返回

        return encrypt.md5(password)

    def clean_confirm_password(self):
        password = self.cleaned_data['password']
        confirm_password = encrypt.md5(self.cleaned_data['confirm_password'])
        if password != confirm_password:
            raise ValidationError("两次密码不一致")
        return confirm_password

    def clean_code(self):
        code = self.cleaned_data['code']
        phone = self.cleaned_data['phone']
        coon = get_redis_connection()
        redis_code = coon.get(phone)
        if not redis_code:
            raise ValidationError("验证码为发送或失效，请重新发送")
        str_code = redis_code.decode('utf-8')
        if code.strip() != str_code:  # strip()去掉空白
            raise ValidationError("验证码验证错误，请重新输入")
        return code


class SendSmsForm(forms.Form):
    phone = forms.CharField(label="手机号", validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机格式错误'), ])

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request

    def clean_phone(self):
        """手机号进行校验的钩子"""
        phone = self.cleaned_data['phone']
        tql = self.request.GET.get('tql')
        template_id = settings.TENCENT_SMS_TEMPLATE.get(tql)
        exists = models.User.objects.filter(phone=phone).exists()
        if tql == 'login':
            if not exists:
                raise ValidationError('手机号不存在')
        else:
            # 验证是否已有手机号
            if exists:
                raise ValidationError("手机已存在")

        # 发短信 写redis

        code = random.randint(1000, 9999)
        coon = get_redis_connection()
        coon.set(phone, code, ex=60)
        # 发短信

        sms = send_sms_single(phone, template_id, [code, ])
        # if sms['result'] != 0:
        #     raise ValidationError("短信发送失败,{}".format(sms['errmsg']))
        #
        # 验证码写入redis

        return phone


class logininSMSForm(BootstrapForm, forms.Form):
    phone = forms.CharField(label='手机号', validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机格式错误'), ])
    code = forms.CharField(label="验证码", widget=forms.TextInput())

    def clean_phone(self):
        phone = self.cleaned_data['phone']
        user_object = models.User.objects.filter(phone=phone).first()
        if not user_object:
            raise ValidationError('手机号不存在')
        return user_object

    def clean_code(self):
        phone = self.cleaned_data['phone']
        code = self.cleaned_data['code']
        coon = get_redis_connection()
        redis_code = coon.get(phone.phone)
        if not redis_code:
            raise ValidationError("验证码为发送或失效，请重新发送")
        str_code = redis_code.decode('utf-8')
        if code.strip() != str_code:  # strip()去掉空白
            raise ValidationError("验证码验证错误，请重新输入")
        return code


class logininForm(BootstrapForm, forms.Form):
    username = forms.CharField(label="邮箱或者手机号")
    password = forms.CharField(label="密码", widget=forms.PasswordInput())
    code = forms.CharField(label="图片验证码")

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request
    def clean_password(self):
        password = self.cleaned_data['password']
        # 加密，并进行返回

        return encrypt.md5(password)

    def clean_code(self):

        """验证图片验证码是否正确"""
        code = self.cleaned_data['code']
        # 去session获取验证码
        session_code = self.request.session.get('image_code')
        if not session_code:
            raise ValidationError("验证码已过期,请重新获取")
        if code.strip().upper() != session_code.upper():
            raise ValidationError("验证码输入错误")
        return code

